package com.yeyaomai.dksns.flowis.dao.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import org.springframework.data.domain.Page;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.mapreduce.GroupBy;
import org.springframework.data.mongodb.core.mapreduce.GroupByResults;
import org.springframework.data.mongodb.core.mapreduce.MapReduceResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Order;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Component;
import com.yeyaomai.dksns.flowis.dao.DkUserInfoDao;
import com.yeyaomai.dksns.flowis.dao.LoginProfileDao;
import com.yeyaomai.dksns.flowis.domain.DkUserInfo;
import com.yeyaomai.dksns.flowis.domain.Login_out;
import com.yeyaomai.dksns.flowis.domain.flowisdetail.FlowisQueryOrder;
import com.yeyaomai.dksns.flowis.domain.flowisdetail.LoginProfile;
import com.yeyaomai.dksns.flowis.page.PageImplResult;
import com.yeyaomai.dksns.flowis.page.PageRequestOrder;
import com.yeyaomai.dksns.flowis.util.Globals;
import com.yeyaomai.dksns.flowis.util.ListPropertyAndValueTool;

@Component
public class LoginProfileDaoImpl implements LoginProfileDao {

	@Resource
	protected MongoTemplate mongoPathTemplate;

	@Resource
	private DkUserInfoDao dkUserInfoDao;

	@Override
	public Page<LoginProfile> getSplit(FlowisQueryOrder order) {

		Query query = new Query();

		for (Map.Entry<String, String> entry : order.getSort().entrySet()) {
			query.sort().on(entry.getKey(), Order.valueOf(entry.getValue()));
		}
		List<String> includeFields = new ArrayList<String>();
		includeFields.add("username");
		includeFields.add("user_dkcode");
		ListPropertyAndValueTool.querySaveCriteria(query, order,
				LoginProfile.class, includeFields);

		PageRequestOrder request = new PageRequestOrder(Integer.parseInt(order
				.getNumber()), order.getPageSize());
		// query.addCriteria(Criteria.where("username").ne(null));
		long totalSize = getTotalSize(query, LoginProfile.class);

		query.skip(request.start()).limit(order.getPageSize());

		List<LoginProfile> ps = mongoPathTemplate.find(query,
				LoginProfile.class);

		Page<LoginProfile> result = new PageImplResult<LoginProfile>(ps,
				request, totalSize);
		return result;
	}

	@Override
	public long getTotalSize(Query query, Class<LoginProfile> document) {
		
		return mongoPathTemplate.count(query, document);
	}

	/**
	 * 定时任务处理newuv
	 * 
	 * @throws IOException
	 */
	public List<DkUserInfo> getDkUserInfo(Integer startTime, Integer endTime) {
		String dkcodes = dkUserInfoDao.getDkcodes();
		String mapFunction = "function() { "
				+ "emit( this.user_dkcode , {username:this.username,distance:this.distance,start_time:1,user_id:this.user_id});  }";

		String reduceFunction = "function(key,values){"
				+ "var ret = {username:0,distance:0,start_time:0,user_id:0};"
				+ "for( var i=0; i<values.length; i++){"
				+ "ret.start_time += 1;"
				+ "ret.username = values[i].username;"
				+ "ret.user_id = values[i].user_id;"
				+ "ret.distance += values[i].distance; " + "} "
				+ "return ret;  }";
		Query query = new Query(Criteria.where("start_time").gte(startTime)
				.lt(endTime));
		MapReduceResults<Login_out> login_outs = this.groupMapReduce(query, mapFunction, reduceFunction,
				Login_out.class);
		List<DkUserInfo> loginList = new ArrayList<DkUserInfo>();
		if (login_outs.getCounts().getOutputCount() != 0) {

			for (Login_out login_out : login_outs) {
				DkUserInfo dkuser = new DkUserInfo();
				LoginProfile login = login_out.getValue();
				dkuser.setUsername(login.getUsername());
				dkuser.setDkcode(Integer.valueOf(login_out.get_id()));
				dkuser.setLogin_num(login.getStart_time());
				dkuser.setOnline_time(login.getDistance());
				dkuser.setIs_internal(1);
				if(null != dkcodes)
				{
					if (dkcodes.indexOf(login_out.get_id()) == -1) {
						dkuser.setIs_internal(0);
					}
				}
				dkuser.setUser_id(login.getUser_id());
				dkuser.setDate(endTime);
				loginList.add(dkuser);
			}
		}
		return loginList;
	}

	public <T> GroupByResults<T> group(Criteria criteria, String key,
			String map, String reduce, Class<T> clas) {

		return mongoPathTemplate.group(criteria, "login_profile",
				GroupBy.key(key).initialDocument(map).reduceFunction(reduce),
				clas);
	}

	public Integer getTotalSizeByUserInfo() {
		String mapFunction = "{ distance: 0}";
		String reduceFunction = "function(key,values) {values.distance+=1}";
		Integer startTime = 0;

		try {
			startTime = (int) (Globals.FORMAT_TYPE_A.parse(
					Globals.FORMAT_TYPE_A.format(new Date())).getTime() / 1000);
		} catch (java.text.ParseException e) {

			e.printStackTrace();
		}

		return this.group(Criteria.where("start_time").gte(startTime),
				"user_dkcode", mapFunction, reduceFunction, LoginProfile.class)
				.getKeys();

	}

public <T> MapReduceResults<T> groupMapReduce(Query query, String map,String reduce, Class<T> clas) {
		
		return mongoPathTemplate.mapReduce(query,  "login_profile", map, reduce, clas);
	}
}
